home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Window.java < prev    next >
Text File  |  1998-09-22  |  22KB  |  726 lines

  1. /*
  2.  * @(#)Window.java    1.77 98/08/13
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.peer.WindowPeer;
  17. import java.awt.event.*;
  18. import java.util.Vector;
  19. import java.util.Locale;
  20. import java.io.Serializable;
  21. import java.io.ObjectOutputStream;
  22. import java.io.ObjectInputStream;
  23. import java.io.IOException;
  24. import sun.awt.im.InputContext;
  25.  
  26.  
  27. /**
  28.  * A <code>Window</code> object is a top-level window with no borders and no
  29.  * menubar. It could be used to implement a pop-up menu.
  30.  * The default layout for a window is <code>BorderLayout</code>.
  31.  * A <code>Window</code> object blocks input to other application 
  32.  * windows when it is shown.
  33.  * <p>
  34.  * Windows are capable of generating the following window events:
  35.  * WindowOpened, WindowClosed.
  36.  *
  37.  * @version     1.77, 08/13/98
  38.  * @author     Sami Shaio
  39.  * @author     Arthur van Hoff
  40.  * @see WindowEvent
  41.  * @see #addWindowListener
  42.  * @see java.awt.BorderLayout
  43.  * @since       JDK1.0
  44.  */
  45. public class Window extends Container {
  46.     String      warningString;
  47.  
  48.     static final int OPENED = 0x01;
  49.     int state;
  50.     transient WindowListener windowListener;
  51.     private transient boolean active;
  52.     
  53.     transient InputContext inputContext;
  54.  
  55.     private FocusManager focusMgr;
  56.  
  57.     private static final String base = "win";
  58.     private static int nameCounter = 0;
  59.  
  60.     /*
  61.      * JDK 1.1 serialVersionUID 
  62.      */
  63.     private static final long serialVersionUID = 4497834738069338734L;
  64.  
  65.     Window() {
  66.     setWarningString();
  67.     this.focusMgr = new FocusManager(this);
  68.     this.visible = false;
  69.     }
  70.  
  71.     /**
  72.      * Construct a name for this component.  Called by getName() when the
  73.      * name is null.
  74.      */
  75.     String constructComponentName() {
  76.         return base + nameCounter++;
  77.     }
  78.  
  79.     /**
  80.      * Constructs a new invisible window.
  81.      * <p>
  82.      * The window is not initially visible. Call the <code>show</code> 
  83.      * method to cause the window to become visible.
  84.      * @param     parent   the main application frame.
  85.      * @see       java.awt.Window#show
  86.      * @see       java.awt.Component#setSize
  87.      * @since     JDK1.0
  88.      */
  89.     public Window(Frame parent) {
  90.     this();
  91.     if (parent == null) {
  92.         throw new IllegalArgumentException("null parent frame");
  93.     }    
  94.     this.parent = parent;
  95.     parent.addOwnedWindow(this);
  96.     setLayout(new BorderLayout());
  97.     }
  98.  
  99.     /**
  100.      * Creates the Window's peer.  The peer allows us to modify the
  101.      * appearance of the Window without changing its functionality.
  102.      */
  103.     public void addNotify() {
  104.       synchronized (getTreeLock()) {
  105.     if (peer == null) {
  106.         peer = getToolkit().createWindow(this);
  107.     }
  108.     super.addNotify();
  109.       }
  110.     }
  111.  
  112.     /**
  113.      * Causes subcomponents of this window to be laid out at their
  114.      * preferred size.
  115.      * @since     JDK1.0
  116.      */
  117.     public void pack() {
  118.     Container parent = this.parent;
  119.     if (parent != null && parent.getPeer() == null) {
  120.         parent.addNotify();
  121.     }
  122.     if (peer == null) {
  123.         addNotify();
  124.     }
  125.     setSize(getPreferredSize());
  126.     validate();
  127.     }
  128.  
  129.     /**
  130.      * Shows this window, and brings it to the front.
  131.      * <p>
  132.      * If this window is not yet visible, <code>show</code> 
  133.      * makes it visible. If this window is already visible, 
  134.      * then this method brings it to the front. 
  135.      * @see       java.awt.Window#toFront
  136.      * @see       java.awt.Component#setVisible
  137.      * @since     JDK1.0
  138.      */
  139.     public void show() {
  140.         Container parent = this.parent;
  141.     if (parent != null && parent.getPeer() == null) {
  142.         parent.addNotify();
  143.     }
  144.     if (peer == null) {
  145.         addNotify();
  146.     }
  147.     validate();
  148.  
  149.     if (visible) {
  150.         toFront();
  151.     } else {
  152.         super.show();
  153.     }
  154.         
  155.         // If first time shown, generate WindowOpened event
  156.         if ((state & OPENED) == 0) {
  157.             postWindowEvent(WindowEvent.WINDOW_OPENED);
  158.             state |= OPENED;
  159.         }
  160.     }
  161.  
  162.     synchronized void postWindowEvent(int id) {
  163.         if (windowListener != null || 
  164.             (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) {
  165.             WindowEvent e = new WindowEvent(this, id);
  166.             Toolkit.getEventQueue().postEvent(e);
  167.         }
  168.     }
  169.         
  170.     /**
  171.      * Disposes of this window. This method must
  172.      * be called to release the resources that
  173.      * are used for the window.
  174.      * @since JDK1.0
  175.      */
  176.     public void dispose() {
  177.       synchronized (getTreeLock()) {
  178.         if (inputContext != null) {
  179.             InputContext toDispose = inputContext;
  180.             inputContext = null;
  181.             toDispose.dispose();
  182.         }
  183.     hide();
  184.     removeNotify();
  185.      if (parent != null) {
  186.         Frame parent = (Frame) this.parent;
  187.         parent.removeOwnedWindow(this);
  188.      } 
  189.         postWindowEvent(WindowEvent.WINDOW_CLOSED);
  190.       }
  191.     }
  192.  
  193.     /**
  194.      * Brings this window to the front.
  195.      * Places this window at the top of the stacking order and
  196.      * shows it in front of any other windows.
  197.      * @see       java.awt.Window#toBack
  198.      * @since     JDK1.0
  199.      */
  200.     public void toFront() {
  201.         WindowPeer peer = (WindowPeer)this.peer;
  202.     if (peer != null) {
  203.         peer.toFront();
  204.     }
  205.     }
  206.  
  207.     /**
  208.      * Sends this window to the back.
  209.      * Places this window at the bottom of the stacking order and
  210.      * makes the corresponding adjustment to other visible windows.
  211.      * @see       java.awt.Window#toFront
  212.      * @since     JDK1.0
  213.      */
  214.     public void toBack() {
  215.         WindowPeer peer = (WindowPeer)this.peer;
  216.     if (peer != null) {
  217.         peer.toBack();
  218.     }
  219.     }
  220.  
  221.     /**
  222.      * Returns the toolkit of this frame.
  223.      * @return    the toolkit of this window.
  224.      * @see       java.awt.Toolkit
  225.      * @see       java.awt.Toolkit#getDefaultToolkit()
  226.      * @see       java.awt.Component#getToolkit()
  227.      * @since     JDK1.0
  228.      */
  229.     public Toolkit getToolkit() {
  230.     return Toolkit.getDefaultToolkit();
  231.     }
  232.  
  233.     /**
  234.      * Gets the warning string that is displayed with this window. 
  235.      * If this window is insecure, the warning string is displayed 
  236.      * somewhere in the visible area of the window. A window is 
  237.      * insecure if there is a security manager, and the security 
  238.      * manager's <code>checkTopLevelWindow</code> method returns 
  239.      * <code>false</code> when this window is passed to it as an
  240.      * argument.
  241.      * <p>
  242.      * If the window is secure, then <code>getWarningString</code>
  243.      * returns <code>null</code>. If the window is insecure, this
  244.      * method checks for the system property 
  245.      * <code>awt.appletWarning</code> 
  246.      * and returns the string value of that property. 
  247.      * @return    the warning string for this window.
  248.      * @see       java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
  249.      * @since     JDK1.0
  250.      */
  251.     public final String getWarningString() {
  252.     return warningString;
  253.     }
  254.  
  255.     private void setWarningString() {
  256.     warningString = null;
  257.     SecurityManager sm = System.getSecurityManager();
  258.     if (sm != null) {
  259.         if (!sm.checkTopLevelWindow(this)) {
  260.         warningString = System.getProperty("awt.appletWarning", 
  261.                            "Warning: Applet Window");
  262.         }
  263.     }
  264.     }
  265.  
  266.     /** 
  267.      * Gets the <code>Locale</code> object that is associated 
  268.      * with this window, if the locale has been set.
  269.      * If no locale has been set, then the default locale 
  270.      * is returned.
  271.      * @return    the locale that is set for this window.
  272.      * @see       java.util.Locale
  273.      * @since     JDK1.1
  274.      */
  275.  
  276.     public Locale getLocale() {
  277.       if (this.locale == null) {
  278.     return Locale.getDefault();
  279.       }
  280.       return this.locale;
  281.     }
  282.  
  283.     /**
  284.      * Gets the input context for this window. A window always has an input context,
  285.      * which is shared by subcomponents unless they create and set their own.
  286.      * @see Component#getInputContext
  287.      */
  288.  
  289.     synchronized InputContext getInputContext() {
  290.  
  291.         if (inputContext == null) {
  292.             inputContext = InputContext.getInstance();
  293.         }
  294.  
  295.         return inputContext;
  296.     }
  297.  
  298.     /**
  299.      * Adds the specified window listener to receive window events from
  300.      * this window.
  301.      * @param l the window listener
  302.      */ 
  303.     public synchronized void addWindowListener(WindowListener l) {
  304.         windowListener = AWTEventMulticaster.add(windowListener, l);
  305.         newEventsOnly = true;
  306.     }
  307.  
  308.     /**
  309.      * Removes the specified window listener so that it no longer
  310.      * receives window events from this window.
  311.      * @param l the window listener
  312.      */ 
  313.     public synchronized void removeWindowListener(WindowListener l) {
  314.         windowListener = AWTEventMulticaster.remove(windowListener, l);
  315.     }
  316.  
  317.     // REMIND: remove when filtering is handled at lower level
  318.     boolean eventEnabled(AWTEvent e) {
  319.         switch(e.id) {
  320.           case WindowEvent.WINDOW_OPENED:
  321.           case WindowEvent.WINDOW_CLOSING:
  322.           case WindowEvent.WINDOW_CLOSED:
  323.           case WindowEvent.WINDOW_ICONIFIED:
  324.           case WindowEvent.WINDOW_DEICONIFIED:
  325.           case WindowEvent.WINDOW_ACTIVATED:
  326.           case WindowEvent.WINDOW_DEACTIVATED:
  327.             if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
  328.                 windowListener != null) {
  329.                 return true;
  330.             }
  331.             return false;
  332.           default:
  333.             break;
  334.         }
  335.         return super.eventEnabled(e);
  336.     }
  337.  
  338.     /**
  339.      * Processes events on this window. If the event is an WindowEvent,
  340.      * it invokes the processWindowEvent method, else it invokes its
  341.      * superclass's processEvent.
  342.      * @param e the event
  343.      */
  344.     protected void processEvent(AWTEvent e) {
  345.         if (e instanceof WindowEvent) {
  346.             processWindowEvent((WindowEvent)e);
  347.             return;
  348.         }
  349.     super.processEvent(e);
  350.     }
  351.  
  352.     /** 
  353.      * Processes window events occurring on this window by
  354.      * dispatching them to any registered WindowListener objects.
  355.      * NOTE: This method will not be called unless window events
  356.      * are enabled for this component; this happens when one of the
  357.      * following occurs:
  358.      * a) A WindowListener object is registered via addWindowListener()
  359.      * b) Window events are enabled via enableEvents()
  360.      * @see Component#enableEvents
  361.      * @param e the window event
  362.      */  
  363.     protected void processWindowEvent(WindowEvent e) {
  364.         if (windowListener != null) {
  365.             switch(e.getID()) {
  366.               case WindowEvent.WINDOW_OPENED:
  367.                 windowListener.windowOpened(e);
  368.                 break;
  369.               case WindowEvent.WINDOW_CLOSING:
  370.                 windowListener.windowClosing(e);
  371.                 break;
  372.               case WindowEvent.WINDOW_CLOSED:
  373.                 windowListener.windowClosed(e);
  374.                 break;
  375.               case WindowEvent.WINDOW_ICONIFIED:
  376.                 windowListener.windowIconified(e);
  377.                 break;
  378.               case WindowEvent.WINDOW_DEICONIFIED:
  379.                 windowListener.windowDeiconified(e);
  380.                 break;
  381.               case WindowEvent.WINDOW_ACTIVATED:
  382.                 windowListener.windowActivated(e);
  383.                 break;
  384.               case WindowEvent.WINDOW_DEACTIVATED:
  385.                 windowListener.windowDeactivated(e);
  386.                 break;
  387.               default:
  388.                 break;
  389.             }
  390.         }
  391.     }
  392.  
  393.     /* Handle TAB and Shift-TAB events. */
  394.     private boolean handleTabEvent(KeyEvent e) {
  395.         if (e.getKeyCode() != '\t' || (e.getSource() instanceof TextArea)) {
  396.             return false;
  397.         }
  398.     if ((e.getModifiers() & ~InputEvent.SHIFT_MASK) > 0) {
  399.         return false;
  400.     }
  401.         int id = e.getID();
  402.     if (id == KeyEvent.KEY_RELEASED || id == KeyEvent.KEY_TYPED) {
  403.         return true;
  404.     }
  405.     if (e.isShiftDown()) {
  406.         return focusMgr.focusPrevious();
  407.     } else {
  408.         return focusMgr.focusNext();
  409.     }
  410.     }
  411.  
  412.     void preProcessKeyEvent(KeyEvent e) {
  413.         // Dump the list of child windows to System.out.
  414.         if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
  415.             e.isControlDown() && e.isShiftDown()) {
  416.             list(System.out, 0);
  417.         }
  418.     }
  419.  
  420.     void postProcessKeyEvent(KeyEvent e) {
  421.         if (handleTabEvent(e)) {
  422.             e.consume();
  423.             return;
  424.         }
  425.     }
  426.  
  427.     void setFocusOwner(Component c) {
  428.     focusMgr.setFocusOwner(c);
  429.     }
  430.  
  431.     void transferFocus(Component base) {
  432.     nextFocus(base);
  433.     }
  434.  
  435.     boolean isActive() {
  436.     return active;
  437.     }
  438.  
  439.     /**
  440.      * Returns the child component of this Window which has focus if and 
  441.      * only if this Window is active.
  442.      * @return the component with focus, or null if no children have focus
  443.      * assigned to them.
  444.      */
  445.     public Component getFocusOwner() {
  446.         if (active)
  447.             return focusMgr.getFocusOwner();
  448.         else
  449.             return null;
  450.     }
  451.  
  452.     /**
  453.      * @deprecated As of JDK version 1.1,
  454.      * replaced by <code>transferFocus(Component)</code>.
  455.      */
  456.     void nextFocus(Component base) {
  457.     focusMgr.focusNext(base);
  458.     }
  459.  
  460.     /*
  461.      * Dispatches an event to this window or one of its sub components.
  462.      * @param e the event
  463.      */
  464.     void dispatchEventImpl(AWTEvent e) {
  465.         switch(e.getID()) {
  466.           case FocusEvent.FOCUS_GAINED:
  467.             setFocusOwner(this);
  468.             break;
  469.           case ComponentEvent.COMPONENT_RESIZED:
  470.             invalidate();
  471.             validate();
  472.             repaint();
  473.             break;
  474.  
  475.           case WindowEvent.WINDOW_ACTIVATED:
  476.             active = true;
  477. /*
  478.   Calling this messes up focus on Solaris
  479.  
  480.             focusMgr.activateFocus();
  481. */
  482.             break;
  483.  
  484.           case WindowEvent.WINDOW_DEACTIVATED:
  485.             active = false;
  486.             break;
  487.  
  488.           default:
  489.             break;
  490.         }
  491.         super.dispatchEventImpl(e);
  492.     }
  493.  
  494.     /**
  495.      * @deprecated As of JDK version 1.1
  496.      * replaced by <code>dispatchEvent(AWTEvent)</code>.
  497.      */
  498.     public boolean postEvent(Event e) {
  499.         if (handleEvent(e)) {
  500.             e.consume();
  501.             return true;
  502.         }
  503.         return false;
  504.     }
  505.  
  506.     /**
  507.      * Checks if this Window is showing on screen.
  508.      * @see java.awt.Component#setVisible(boolean)
  509.      */
  510.     public boolean isShowing() {
  511.     return visible;
  512.     }
  513.  
  514.     /* Serialization support.  If there's a MenuBar we restore
  515.      * its (transient) parent field here.
  516.      */
  517.  
  518.     private int windowSerializedDataVersion = 1;
  519.  
  520.  
  521.     private void writeObject(ObjectOutputStream s)
  522.       throws IOException 
  523.     {
  524.       s.defaultWriteObject();
  525.  
  526.       AWTEventMulticaster.save(s, windowListenerK, windowListener);
  527.       s.writeObject(null);
  528.     }
  529.  
  530.  
  531.     private void readObject(ObjectInputStream s)
  532.       throws ClassNotFoundException, IOException 
  533.     {
  534.       s.defaultReadObject();
  535.  
  536.       Object keyOrNull;
  537.       while(null != (keyOrNull = s.readObject())) {
  538.     String key = ((String)keyOrNull).intern();
  539.  
  540.     if (windowListenerK == key) 
  541.       addWindowListener((WindowListener)(s.readObject()));
  542.  
  543.     else // skip value for unrecognized key
  544.       s.readObject();
  545.       }
  546.       setWarningString();
  547.     }
  548.  
  549. }
  550.  
  551.  
  552. class FocusManager implements java.io.Serializable {
  553.     Container focusRoot;
  554.     Component focusOwner; //Bug #4101153 : a backout for b fix made for 
  555.                             //bug # 4092347
  556.  
  557.     /*
  558.      * JDK 1.1 serialVersionUID 
  559.      */
  560.     static final long serialVersionUID = 2491878825643557906L;
  561.  
  562.     FocusManager(Container cont) {
  563.     focusRoot = cont;
  564.     }
  565.  
  566.     /* Re-activate the last component with focus if it is still
  567.      * visible and active.
  568.      * If no component had focus yet, assign it to first component
  569.      * capable of receiving it (visible, active, focusable).
  570.      * If no visible, active, focusable components are present,
  571.      * assign focus to the focus root.
  572.      */
  573.     void activateFocus() {
  574.         boolean assigned = false;
  575.         if (focusOwner != null) {
  576.             if ((assigned = assignFocus(focusOwner, false)) != true) {
  577.                 assigned = focusNext(focusOwner);
  578.             }
  579.         } else {
  580.             // assign to first component capable of taking it
  581.             assigned = focusForward(focusRoot);
  582.         }
  583.         if (!assigned) {
  584.             focusRoot.requestFocus(); 
  585.         }
  586.     }                
  587.                 
  588.      
  589.     synchronized void setFocusOwner(Component c) {
  590.         focusOwner = c;
  591.     }
  592.  
  593.     Component getFocusOwner() {
  594.        return focusOwner;
  595.     }
  596.     
  597.     boolean focusNext() {
  598.        return focusNext(focusOwner);
  599.     }
  600.  
  601.     boolean focusNext(Component base) {
  602.         synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  603.             Component target = base;
  604.             if (target != null && target.parent != null) {
  605.                 //System.out.println("FocusManager.focusNext: owner="+focusOwner);
  606.                 do {
  607.                     boolean found = false;
  608.                     Container p = target.parent;
  609.                     Component c;
  610.                     for (int i = 0; i < p.ncomponents; i++) {
  611.                         c = p.component[i];
  612.                         if (found) {
  613.                             if (assignFocus(c)) {
  614.                                 return true;
  615.                             }
  616.                             if (c instanceof Container && 
  617.                                     c.isVisible() && 
  618.                                     c.isEnabled()) {
  619.                                 if (focusForward((Container)c)) {
  620.                                     return true;
  621.                                 }
  622.                             }         
  623.                         } else if (c == target) {
  624.                             found = true;    
  625.                         }
  626.                     } 
  627.                     target = p;
  628.                 } while (target != focusRoot && target.parent != null);
  629.             }
  630.             // wrap-around
  631.             if (focusForward(focusRoot)) {
  632.                 return true;
  633.             }
  634.     
  635.             return false;        
  636.         }
  637.     }
  638.  
  639.  
  640.     boolean focusPrevious() {
  641.         return focusPrevious(focusOwner);
  642.     }
  643.     
  644.     boolean focusPrevious(Component base) {
  645.         synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  646.             Component target = base;
  647.             if (target != null && target.parent != null) {
  648.                 do {
  649.                     boolean found = false;
  650.                     Container p = target.parent;
  651.                         Component c;
  652.                     for (int i = p.ncomponents-1; i >= 0; i--) {
  653.                         c = p.component[i];
  654.                         if (found) {
  655.                             if (assignFocus(c)) {
  656.                                 return true;
  657.                             }
  658.                             if (c instanceof Container && 
  659.                                     c.isVisible() && 
  660.                                     c.isEnabled()) {
  661.                                 if (focusBackward((Container)c)) {
  662.                                     return true;
  663.                                 }
  664.                              }         
  665.                          } else if (c == target) {
  666.                              found = true;    
  667.                          }
  668.                     } 
  669.                     target = p;
  670.                 } while (target != focusRoot);
  671.  
  672.             }
  673.                             // wrap-around
  674.             if (focusBackward(focusRoot)) {
  675.                 return true;
  676.             }
  677.             return false;        
  678.         }
  679.     }
  680.  
  681.     boolean assignFocus(Component c) {
  682.         return assignFocus(c, true);
  683.     }
  684.  
  685.     synchronized boolean assignFocus(Component c, boolean requireTraversable) {
  686.         if (c.isVisible() && c.isEnabled() &&
  687.             (!requireTraversable || c.isFocusTraversable())) {
  688.             //System.out.println("FocusManager.assignFocus: "+c);
  689.             c.requestFocus();
  690.             return true;
  691.         }
  692.         return false;
  693.     }
  694.  
  695.     synchronized boolean focusForward(Container cont) {
  696.         for (int i = 0; i < cont.ncomponents; i++) {
  697.             Component c = cont.component[i];
  698.             if (assignFocus(c)) {
  699.                 return true;
  700.             }
  701.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  702.                 if (focusForward((Container)c)) {
  703.                     return true;
  704.                 }
  705.             } 
  706.         }
  707.         return false;
  708.     }
  709.  
  710.     synchronized boolean focusBackward(Container cont) {
  711.         for (int i = cont.ncomponents-1; i >= 0; i--) {
  712.             Component c = cont.component[i];
  713.             if (assignFocus(c)) {
  714.                 return true;
  715.             }
  716.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  717.                 if (focusBackward((Container)c)) {
  718.                     return true;
  719.                 }
  720.             } 
  721.         }
  722.         return false;
  723.     }
  724.  
  725. }
  726.